Skip to content

[lldb][AIX] get host info for AIX (cont..) #138687

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 5 commits into from
May 29, 2025

Conversation

HemangGadhavi
Copy link
Contributor

@HemangGadhavi HemangGadhavi commented May 6, 2025

This PR is in reference to porting LLDB on AIX.

Link to discussions on llvm discourse and github:

  1. https://discourse.llvm.org/t/port-lldb-to-ibm-aix/80640
  2. Extending LLDB to work on AIX #101657
    The complete changes for porting are present in this draft PR:
    Extending LLDB to work on AIX #102601

@llvmbot llvmbot added the lldb label May 6, 2025
@llvmbot
Copy link
Member

llvmbot commented May 6, 2025

@llvm/pr-subscribers-lldb

Author: Hemang Gadhavi (HemangGadhavi)

Changes

This PR is in reference to porting LLDB on AIX.

Link to discussions on llvm discourse and github:

  1. https://discourse.llvm.org/t/port-lldb-to-ibm-aix/80640
  2. Extending LLDB to work on AIX #101657
    The complete changes for porting are present in this draft PR:
    Extending LLDB to work on AIX #102601

Full diff: https://github.com/llvm/llvm-project/pull/138687.diff

2 Files Affected:

  • (modified) lldb/source/Host/aix/Host.cpp (+48-1)
  • (modified) lldb/source/Host/aix/HostInfoAIX.cpp (+15)
diff --git a/lldb/source/Host/aix/Host.cpp b/lldb/source/Host/aix/Host.cpp
index a812e061ccae2..ead8202cbbdef 100644
--- a/lldb/source/Host/aix/Host.cpp
+++ b/lldb/source/Host/aix/Host.cpp
@@ -13,6 +13,7 @@
 #include "lldb/Utility/ProcessInfo.h"
 #include "lldb/Utility/Status.h"
 #include "llvm/BinaryFormat/XCOFF.h"
+#include <dirent.h>
 #include <sys/proc.h>
 #include <sys/procfs.h>
 
@@ -41,6 +42,14 @@ static ProcessInstanceInfo::timespec convert(pr_timestruc64_t t) {
   return ts;
 }
 
+static bool IsDirNumeric(const char *dname) {
+  for (; *dname; dname++) {
+    if (!isdigit(*dname))
+      return false;
+  }
+  return true;
+}
+
 static bool GetStatusInfo(::pid_t pid, ProcessInstanceInfo &processInfo,
                           ProcessState &State) {
   struct pstatus pstatusData;
@@ -133,7 +142,45 @@ static bool GetProcessAndStatInfo(::pid_t pid,
 
 uint32_t Host::FindProcessesImpl(const ProcessInstanceInfoMatch &match_info,
                                  ProcessInstanceInfoList &process_infos) {
-  return 0;
+  static const char procdir[] = "/proc/";
+
+  DIR *dirproc = opendir(procdir);
+  if (dirproc) {
+    struct dirent *direntry = nullptr;
+    const uid_t our_uid = getuid();
+    const lldb::pid_t our_pid = getpid();
+    bool all_users = match_info.GetMatchAllUsers();
+
+    while ((direntry = readdir(dirproc)) != nullptr) {
+      if (!IsDirNumeric(direntry->d_name))
+        continue;
+
+      lldb::pid_t pid = atoi(direntry->d_name);
+      // Skip this process.
+      if (pid == our_pid)
+        continue;
+
+      ProcessState State;
+      ProcessInstanceInfo process_info;
+      if (!GetProcessAndStatInfo(pid, process_info, State))
+        continue;
+
+      if (State == ProcessState::Zombie ||
+          State == ProcessState::TracedOrStopped)
+        continue;
+
+      // Check for user match if we're not matching all users and not running
+      // as root.
+      if (!all_users && (our_uid != 0) && (process_info.GetUserID() != our_uid))
+        continue;
+
+      if (match_info.Matches(process_info)) {
+        process_infos.push_back(process_info);
+      }
+    }
+    closedir(dirproc);
+  }
+  return process_infos.size();
 }
 
 bool Host::GetProcessInfo(lldb::pid_t pid, ProcessInstanceInfo &process_info) {
diff --git a/lldb/source/Host/aix/HostInfoAIX.cpp b/lldb/source/Host/aix/HostInfoAIX.cpp
index 61b47462dd647..d720f5c52d3b1 100644
--- a/lldb/source/Host/aix/HostInfoAIX.cpp
+++ b/lldb/source/Host/aix/HostInfoAIX.cpp
@@ -7,6 +7,8 @@
 //===----------------------------------------------------------------------===//
 
 #include "lldb/Host/aix/HostInfoAIX.h"
+#include "lldb/Host/posix/Support.h"
+#include <sys/procfs.h>
 
 using namespace lldb_private;
 
@@ -18,5 +20,18 @@ void HostInfoAIX::Terminate() { HostInfoBase::Terminate(); }
 
 FileSpec HostInfoAIX::GetProgramFileSpec() {
   static FileSpec g_program_filespec;
+  struct psinfo psinfoData;
+  auto BufferOrError = getProcFile(getpid(), "psinfo");
+  if (BufferOrError) {
+    std::unique_ptr<llvm::MemoryBuffer> PsinfoBuffer =
+        std::move(*BufferOrError);
+    memcpy(&psinfoData, PsinfoBuffer->getBufferStart(), sizeof(psinfoData));
+    llvm::StringRef exe_path(
+        psinfoData.pr_psargs,
+        strnlen(psinfoData.pr_psargs, sizeof(psinfoData.pr_psargs)));
+    if (!exe_path.empty()) {
+      g_program_filespec.SetFile(exe_path, FileSpec::Style::native);
+    }
+  }
   return g_program_filespec;
 }

Copy link
Collaborator

@labath labath left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Could you also make unit tests for these two functions:

  • call GetProgramFileSpec and make sure the result is reasonable (exists?)
  • create a Process and make sure FindProcesses finds it (you can use this trick to re-execute yourself)

@HemangGadhavi
Copy link
Contributor Author

Could you also make unit tests for these two functions:

  • call GetProgramFileSpec and make sure the result is reasonable (exists?)
  • create a Process and make sure FindProcesses finds it (you can use this trick to re-execute yourself)

Hi @labath
Created the testcases for the GetProgramFileSpec & FindProcesses.

But for the FindProcesses() testcase, we are able to launch the process but later point we are seeing dump on the testcase.
Could you please verify are we giving the input correctly or missing something?
from the logs we can see that GetProcessAndStatInfo() (which is invoked from GetProcessInfo() & FindProcesses()) dumping the core specifically while calling GetExePathAndArch() function on linux.
Could you please help to guide on that.?

@HemangGadhavi HemangGadhavi requested a review from labath May 21, 2025 09:36
TEST_F(HostInfoTest, GetProgramFileSpec) {
// Test GetProgramFileSpec()
FileSpec filespec = HostInfo::GetProgramFileSpec();
EXPECT_FALSE(filespec.GetFilename().IsEmpty());
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Let's make this stronger. We should at least be able to check that it exists.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done Please verify once @labath

Copy link
Contributor

@DhruvSrivastavaX DhruvSrivastavaX May 23, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@labath Does it need to be more like a step-by-step/combination check?
Like checking the Path validity, then checking if it exists or something like that?
Or just one strong check like "exists" is enough?

@labath
Copy link
Collaborator

labath commented May 21, 2025

Could you also make unit tests for these two functions:

  • call GetProgramFileSpec and make sure the result is reasonable (exists?)
  • create a Process and make sure FindProcesses finds it (you can use this trick to re-execute yourself)

Hi @labath Created the testcases for the GetProgramFileSpec & FindProcesses.

But for the FindProcesses() testcase, we are able to launch the process but later point we are seeing dump on the testcase. Could you please verify are we giving the input correctly or missing something? from the logs we can see that GetProcessAndStatInfo() (which is invoked from GetProcessInfo() & FindProcesses()) dumping the core specifically while calling GetExePathAndArch() function on linux. Could you please help to guide on that.?

I'll take a look. I don't know if this is the source of the problem, but one thing I noticed is that you're missing some sort of synchronization to make sure the child process doesn't exit before you're able to observe it. A slightly lame but probably sufficient method to do that would be to put a long (say, 1 minute, it's there just to ensure the process exits if something goes wrong) sleep into the child, and then have the parent kill it when it is done with it.

@labath
Copy link
Collaborator

labath commented May 21, 2025

The failure is in lldb_private::HostInfoBase::GetArchitecture. To fix this, you need to Initialize() the HostInfo class.

@HemangGadhavi
Copy link
Contributor Author

The failure is in lldb_private::HostInfoBase::GetArchitecture. To fix this, you need to Initialize() the HostInfo class.

Thank you @labath. Thanks for the guidance, it worked.
Could you please review and give your comments.

@HemangGadhavi HemangGadhavi requested a review from labath May 22, 2025 11:52
@labath
Copy link
Collaborator

labath commented May 23, 2025

I don't know if this is the source of the problem, but one thing I noticed is that you're missing some sort of synchronization to make sure the child process doesn't exit before you're able to observe it. A slightly lame but probably sufficient method to do that would be to put a long (say, 1 minute, it's there just to ensure the process exits if something goes wrong) sleep into the child, and then have the parent kill it when it is done with it.

The code looks good, but you still need to do something to ensure there's no race in retrieving the process info.

@HemangGadhavi
Copy link
Contributor Author

I don't know if this is the source of the problem, but one thing I noticed is that you're missing some sort of synchronization to make sure the child process doesn't exit before you're able to observe it. A slightly lame but probably sufficient method to do that would be to put a long (say, 1 minute, it's there just to ensure the process exits if something goes wrong) sleep into the child, and then have the parent kill it when it is done with it.

The code looks good, but you still need to do something to ensure there's no race in retrieving the process info.

Hi @labath Added some delay which gives some time before retrieving the process info.
Please review once.

@DhruvSrivastavaX
Copy link
Contributor

Side-Note: @HemangGadhavi Please verify that these pass on our AIX setup as well.

Copy link
Collaborator

@labath labath left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Added some delay

You did, but to the wrong place. What I'm trying to ensure is that the child process does not exit before we can observe it. This makes that failure mode even likelier.

Take a look at the suggested edits to see what I had in mind.

@DhruvSrivastavaX DhruvSrivastavaX merged commit f4e1ec5 into llvm:main May 29, 2025
10 checks passed
svkeerthy pushed a commit that referenced this pull request May 29, 2025
This PR is in reference to porting LLDB on AIX.

Link to discussions on llvm discourse and github:

1. https://discourse.llvm.org/t/port-lldb-to-ibm-aix/80640
2. #101657
The complete changes for porting are present in this draft PR:
#102601

- Added testcase for `GetProgramFileSpec()` & `FindProcesses()`
- Added changes to get the host information for AIX (info like
FindProcessesImpl() GetProgramFileSpec()),
continue from the PR #134354
google-yfyang pushed a commit to google-yfyang/llvm-project that referenced this pull request May 29, 2025
This PR is in reference to porting LLDB on AIX.

Link to discussions on llvm discourse and github:

1. https://discourse.llvm.org/t/port-lldb-to-ibm-aix/80640
2. llvm#101657
The complete changes for porting are present in this draft PR:
llvm#102601

- Added testcase for `GetProgramFileSpec()` & `FindProcesses()`
- Added changes to get the host information for AIX (info like
FindProcessesImpl() GetProgramFileSpec()),
continue from the PR llvm#134354
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants